﻿//使用SIFT进行特征匹配

#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat image01 = imread("E://VC_project//figure//book//imageProcessing1.jpg");
	Mat image02 = imread("E://VC_project//figure//book//imageProcessing2.jpg");

	resize(image01, image01, Size(image01.cols / 6, image01.rows / 6));
	resize(image02, image02, Size(image02.cols / 6, image02.rows / 6));

	Mat gray1, gray2;
	cvtColor(image01, gray1, COLOR_RGB2GRAY);
	cvtColor(image02, gray2, COLOR_RGB2GRAY);


	//创建sift算子
	Ptr<Feature2D>sift = xfeatures2d::SIFT::create();
	
	vector<KeyPoint>keypoints1, keypoints2; //保存特征点
	Mat descriptors1, descriptors2; //保存描述子向量

	//同时检测特征点和描述子向量
	sift->detectAndCompute(gray1, Mat(), keypoints1, descriptors1);
	sift->detectAndCompute(gray2, Mat(), keypoints2, descriptors2);

	//实例化匹配器
	FlannBasedMatcher matcher;

	//保存匹配的特征点
	vector<vector<DMatch>> matches;

	vector<Mat> train_desc(1, descriptors1);
	matcher.add(train_desc);
	matcher.train();

	matcher.knnMatch(descriptors2, matches, 2);
	

	//获取更优秀的匹配点
	vector<DMatch> goodMatches;
	for (int i = 0; i < matches.size(); i++)
	{
		if (matches[i][0].distance < 0.6*matches[i][1].distance)
		{
			goodMatches.push_back(matches[i][0]);
		}
	}

	//画出匹配图
	Mat imageMatch;
	drawMatches(image02, keypoints2, image01, keypoints1, goodMatches, imageMatch);

	imshow("image01", image01);
	imshow("image02", image02);
	imshow("match", imageMatch);
	imwrite("vision_match.jpg", imageMatch);
	waitKey();
    
}

